home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////////////////////////////
- // FILENAME: eTLink.m
- // SUMMARY: Implementation of link buttons in eText documents
- // SUPERCLASS: Object:eTImage
- // INTERFACE: None
- // PROTOCOLS: <Annotation,HTMDSupport,ASCIISupport,LaTeXSupport,Tool,
- // InspectableTarget>
- // AUTHOR: Rohit Khare
- // COPYRIGHT: (c) 1994 California Institure of Technology, eText Project
- ///////////////////////////////////////////////////////////////////////////////
- // DESCRIPTION
- // Does its job by holding doc/anchorIDs and yelling at NXApp.
- ///////////////////////////////////////////////////////////////////////////////
- // HISTORY
- // 10/30/94: Modified to support <InspectableTarget>
- // 07/21/94: Revamped for PR1 and eTImage[Component] support
- // 07/09/94: URLRep added by RK and TRZ (Removed 7/21)
- // 07/07/94: Rewritten as subclass of imageAnnotation
- // 07/03/94: Added eTLinkUI integration for image-links.
- // 06/17/94: HTMDSupport added. RK and TRZ
- // 02/04/94: Created. First actual implementation.
- ///////////////////////////////////////////////////////////////////////////////
-
- #import "eTLink.h"
- #define _eTLinkVERSION 10
-
- @implementation eTLink
- // long anchorID;
- // long docID;
- // etfLink theLink;
- // NXAtom URLRep;
-
- + toolAwake:theApp
- {
- [theApp registerAnnotation: [eTLink class]
- name: "eTLink"
- RTFDirective: "eTLink"
- menuLabel: NULL
- menuKey: '\0'
- menuIcon: (NXImage *) nil];
- [theApp registerType:NXCreateFileContentsPboardType("etfd") for:[eTLink class]];
- [theApp registerType:NXCreateFileContentsPboardType("etfLink") for:[eTLink class]];
- return self;
- }
-
- - init
- {
- [super init];
-
- docID = anchorID = 0;
- theLink.docID = theLink.anchorID = theLink.docTitle = theLink.anchorTitle
- = NXUniqueString("");
- [self setImageComponent:[eTImageComponent newImageNamed:"NXLinkButton"]];
- [self setAltImageComponent:[eTImageComponent newImageNamed:"NXLinkButtonH"]];
- [self setDraggable:YES];
- return self;
- }
-
- - free
- {
- return self = [super free];
- }
- - setImageComponent:newImageComponent
- {
- const char *name;
-
- name = [[newImageComponent theImage] name];
- if (name && !strcmp(name,"NXLinkButton"))
- usesButtonStyle = NO;
- else
- usesButtonStyle = YES;
- return [super setImageComponent:newImageComponent];
- }
- - initFromPboard:thePB inDoc:theDoc linked:(BOOL) linked
- {
- NXAtom types[5];
- char *data;
- int len;
-
- [super initFromPboard:thePB inDoc:theDoc linked: linked];
- [self init];
- types[0] = NXCreateFileContentsPboardType("etfLink");
- types[1] = NXCreateFileContentsPboardType("etfd");
- types[2] = NXCreateFileContentsPboardType(ANY_TYPE);
- types[3] = NXFilenamePboardType;
- types[4] = [thePB findAvailableTypeFrom:types num:4];
-
- if (!types[4]) return self;
- if (types[4]) {
- [thePB readType:NXFilenamePboardType data:&data length:&len];
- if (index(data,'\t')) *(index(data,'\t'))=0;
- [self initFromFile:data];
- [thePB deallocatePasteboardData:data length:len];
- } else {
- NXLogError("%s got fcontents without fnamepboard! %s instead.",
- [[self class] name], types[4]);
- }
- return self;
- }
-
- - initFromFile: (const char *) theFile
- {
- id theTable;
-
- [self init];
- if (!strcmp("etfLink", rindex(theFile, '.')+1)) {
- theTable = [[NXStringTable alloc] init];
- if ([theTable readFromFile:theFile]) {
- sscanf([theTable valueForStringKey:DOCID], "%x", &docID);
- sscanf([theTable valueForStringKey:ANCHORID],
- "%x", &anchorID);
- theLink.docID = NXUniqueString([theTable valueForStringKey:DOCID]);
- theLink.anchorID = NXUniqueString([theTable valueForStringKey:ANCHORID]);
- theLink.docTitle = NXUniqueString([theTable valueForStringKey:DOCTITLE]);
- theLink.anchorTitle = NXUniqueString([theTable valueForStringKey:ANCHORTITLE]);
- }
- theTable = [[theTable empty] free]; // free even if read from file failed
- } else if (!strcmp(ETFD_EXT, rindex(theFile, '.')+1)) {
- // find a docID for this file, stash it away
- theTable = [[[eTDocInfo alloc] init] readComponentFromPath:theFile];
- if (theTable){
- docID = [theTable docID];
- anchorID = 0;
- theLink.docID = NXUniqueString([theTable docIDStr]);
- theLink.anchorID = NXUniqueString("0");
- theLink.anchorTitle = theLink.docTitle = NXUniqueString([theTable title]);
- theTable = [theTable free];
- }
- } else {
- NXLogError("eTLink asked to init from:%s; cannot.", theFile);
- }
- return self;
- }
-
- - readRichText:(NXStream *)stream forView:view
- {
- int i;
- char buf[MAXPATHLEN];
-
- NXScanf(stream, "%d ", &i);
- if (i != _eTLinkVERSION) {
- // bad version block.
- NXLogError("eTLink found unparseable version %d at position %d",
- i, NXTell(stream));
- return nil;
- }
-
- NXScanf(stream, "%s ", buf);
- theLink.docID = NXUniqueString(buf);
- sscanf(theLink.docID, "%x", &docID);
-
- NXScanf(stream, "%s", buf);
- theLink.anchorID = NXUniqueString(buf);
- sscanf(theLink.anchorID, "%x", &anchorID);
-
- NXScanf(stream, "%d", &i); NXGetc(stream); //space-eater
- if (i) NXRead(stream, buf, i);
- buf[i] = 0;
- theLink.docTitle = NXUniqueString(buf);
-
- NXScanf(stream, "%d", &i); NXGetc(stream); //space-eater
- if (i) NXRead(stream, buf, i);
- buf[i] = 0;
- theLink.anchorTitle = NXUniqueString(buf);
-
- NXGetc(stream); // extra space char.
- [super readRichText:stream forView:view];
- return self;
- }
-
- - writeRichText:(NXStream *)stream forView:view
- {
- id dI=nil;
-
- // maintain docID-docTitle consistency
- dI = [eTDocInfo findDocInfo:docID];
- if (dI) theLink.docTitle= NXUniqueString([dI docTitle]);
- NXPrintf(stream, "%d %s %s %d %s %d %s ", _eTLinkVERSION,
- theLink.docID, theLink.anchorID,
- strlen(theLink.docTitle), theLink.docTitle,
- strlen(theLink.anchorTitle), theLink.anchorTitle);
- [super writeRichText:stream forView:view];
- return self;
- }
-
- - writeASCIIRef:(NXStream *)stream forView:view
- {
- if(*theLink.docID) {
- if(theLink.anchorID && anchorID)
- NXPrintf(stream, "See %y in %y [%s in %s]\n\t", theLink.anchorTitle, theLink.docTitle, theLink.anchorID, theLink.docID);
- else
- NXPrintf(stream, "See %y [%s]\n\t", theLink.docTitle, theLink.docID);
- }
- [super writeASCIIRef:stream forView:view];
- return self;
- }
-
- - writeLaTeX:(NXStream*)stream forView:view
- {
- [super writeLaTeX:stream forView:view];
- if(*theLink.docID) {
- if(theLink.anchorID && anchorID)
- NXPrintf(stream, "\n\\footnote{See %w in %w [%w in %w]}\n", theLink.anchorTitle, theLink.docTitle, theLink.anchorID, theLink.docID);
- else
- NXPrintf(stream, "\n\\footnote{See %w [%w]}\n", theLink.docTitle, theLink.docID);
- }
- return self;
- }
-
- - writeHTML:(NXStream *)stream forView:view
- {
- char tmp[MAXPATHLEN];
-
- id theDocInfo = [eTDocInfo findDocInfo:docID];
- if(!theDocInfo) return self;
-
- if(*theLink.docID) {
- strcpy(tmp, [theDocInfo docPath]);
- *rindex(tmp,'.')=0;
- NXPrintf(stream,"<A HREF=\"../%V."HTMD_EXT"/"HTML_INDEX,rindex(tmp,'/')+1);
- if(anchorID) NXPrintf(stream,"#%s", theLink.anchorID);
- NXPrintf(stream, "\">");
- // if (theLink.anchorTitle && *theLink.anchorTitle) {
- // NXPrintf(stream,"\"><%v>", theLink.anchorTitle);
-
- [super writeHTML:stream forView:view];
- NXPrintf(stream,"</A>");
-
- // }
- // else
- // NXPrintf(stream,"\"><Click Here></A>");
- }
- return self;
- }
- #define NXLINK "NXLinkButton"
- #define NXLINK_GIF NXLINK".gif"
- - writeComponentToPath:(NXAtom)path inFormat:(int) theFormat
- {
- const char *name;
-
- if(!etDoc) NXLogError("etDoc is nil at %s %u",__FILE__,__LINE__);
- name = [[imageComponent theImage] name];
- if ((theFormat == HTMD_FMT) && name && !strcmp(name,NXLINK)) {
- char cmd[2*MAXPATHLEN];
-
- sprintf(cmd,"%s/"NXLINK_GIF, [[NXBundle mainBundle] directory]);
- if (!access(cmd, F_OK|R_OK)) {
- sprintf(cmd,"cp -rp \"%s/"NXLINK_GIF"\" \"%s/"NXLINK_GIF"\"",
- [[NXBundle mainBundle] directory], path);
- system(cmd);
- [etDoc registerComponent:NXLINK_GIF];
- } else {
- [super writeComponentToPath:path inFormat:theFormat];
- }
- } else
- [super writeComponentToPath:path inFormat:theFormat];
- return self;
- }
-
- - doubleClick2:sender
- {
- if (docID && [eTDocInfo findDocInfo:docID]) {
- [[NXApp etApp] openID:docID];
- [[[objc_lookUpClass("eTBookmarkBinder") new] bookmarkForID:anchorID] highlight:sender];
- } else {
- NXRunAlertPanel("eTLink", "Could not locate docID %x","OK", NULL, NULL,docID);
- }
- return self;
- }
-
- - doubleClick:(NXEvent *) e
- {
- [self perform:@selector(doubleClick2:) with:self afterDelay:0
- cancelPrevious:YES];
- return self;
- }
-
- - inspect:(NXEvent *) e
- {
- [[NXApp inspector] inspect:self];
- return self;
- }
- - (id <Inspectable>) inspectableDelegate {
- return [[eTLinkUI new] setAnnotation:self]; }
-
- - (NXAtom)anchorTitle
- {return ((theLink.anchorTitle) ? theLink.anchorTitle : "");}
- - (NXAtom)anchorID
- {return ((theLink.anchorID) ? theLink.anchorID : "");}
- - (NXAtom)docTitle
- {return ((theLink.docTitle) ? theLink.docTitle : "");}
- - (NXAtom)docID
- {return ((theLink.docID) ? theLink.docID : "");}
-
- - drag: (Pasteboard *)draggingPboard image:(NXImage **)proxyImage
- {
- id theTable;
- char filename[MAXPATHLEN];
-
- theTable = [[NXStringTable alloc] init];
- [theTable insertKey:DOCID
- value: NXCopyStringBuffer(theLink.docID)];
- [theTable insertKey:ANCHORID
- value: NXCopyStringBuffer(theLink.anchorID)];
- [theTable insertKey:DOCTITLE value:
- NXCopyStringBuffer(theLink.docTitle)];
- [theTable insertKey:ANCHORTITLE value:
- NXCopyStringBuffer(theLink.anchorTitle)];
- sprintf(filename, "/tmp/%s.etfLink", theLink.anchorTitle);
- [theTable writeToFile:filename];
- theTable = [[theTable empty] free];
-
- [draggingPboard declareTypes:&NXFilenamePboardType num:1 owner:nil];
- [draggingPboard writeType: NXFilenamePboardType data: filename
- length: strlen(filename)];
- *proxyImage = [[eTImageComponent newImageNamed:"NXLinkButton"] theImage];
- return self;
- }
- @end